#pragma once

#include"Common.hpp"
#include"EventLoop.hpp"
#include"Channel.hpp"
#include"TcpSocket.hpp"
#include"LoopThreadPool.hpp"
#include"Acceptor.hpp"
#include"Connection.hpp"
class TcpServer
{
private:
    uint64_t _next_id; // 这是⼀个⾃动增⻓的连接ID，
    int _port;
    int _timeout;                  // 这是⾮活跃连接的超时时间---多⻓时间⽆通信就是⾮活跃连接
    bool _enable_inactive_release; // 是否启动了⾮活跃连接超时销毁的判断标志
    EventLoop _baseloop;           // 这是主线程的EventLoop对象，负责监听事件的处理
    Acceptor _acceptor;            // 这是监听套接字的管理对象
    LoopThreadPool _pools;          // 这是从属EventLoop线程池
    // 保存管理所有连接对应的shared_ptr对象
    std::unordered_map<uint64_t, ConnectionPtr> _conns;
    using ConnectedCallback = std::function<void(const ConnectionPtr &)>;
    using MessageCallback = std::function<void(const ConnectionPtr &, Buffer *)>;
    using ClosedCallback = std::function<void(const ConnectionPtr &)>;
    using AnyEventCallback = std::function<void(const ConnectionPtr &)>;
    using Functor = std::function<void()>;
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    ClosedCallback _closed_callback;
    AnyEventCallback _event_callback;

private:
    //设置超时任务
    void RunAfterInLoop(const Functor &task, int delay)
    {
        _next_id++;
        _baseloop.TimerAdd(_next_id, delay, task);
    }
    // 为新连接构造⼀个Connection进⾏管理
    void NewConnection(int fd)
    {
        LOG(DEBUG,"监听器触发可读回调函数创建NewConnection!\n");
        // sleep(1000);
        _next_id++;
        ConnectionPtr conn(new Connection(_next_id, fd, _pools.Dispatch()));
        conn->SetMessageCallback(_message_callback);
        conn->SetClosedCallback(_closed_callback);
        conn->SetConnectedCallback(_connected_callback);
        conn->SetAnyEventCallback(_event_callback);
        conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
        // 启动⾮活跃超时销毁
        if (_enable_inactive_release)
        {
            LOG(DEBUG,"Connection设置非活跃连接完毕! 连接id: %d,超时时间: %d\n",_next_id,_timeout);
            conn->EnableInactiveRelease(_timeout);
        }
        conn->Established(); // 就绪初始化
        _conns.insert(std::make_pair(_next_id, conn));
    }
    void RemoveConnectionInLoop(const ConnectionPtr &conn)
    {
        int id = conn->Id();
        auto it = _conns.find(id);
        if (it != _conns.end())
        {
            _conns.erase(it);
        }
    }
    // 从管理Connection的_conns中移除连接信息
    void RemoveConnection(const ConnectionPtr &conn)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
    }

public:
    TcpServer(int port) : _port(port),
                          _next_id(0),
                          _enable_inactive_release(false),
                          _acceptor(&_baseloop, port),
                          _pools(&_baseloop)
    {
        _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection,
                                              this, std::placeholders::_1));
        _acceptor.Listen(); // 将监听套接字挂到baseloop上
    }
    void SetThreadCount(int count)
    {
        return _pools.SetThreadNums(count);
    }
    void SetConnectedCallback(const ConnectedCallback &cb)
    {
        _connected_callback = cb;
    }
    void SetMessageCallback(const MessageCallback &cb)
    {
        _message_callback = cb;
    }
    void SetClosedCallback(const ClosedCallback &cb)
    {
        _closed_callback = cb;
    }
    void SetAnyEventCallback(const AnyEventCallback &cb)
    {
        _event_callback = cb;
    }
    //开启非活跃连接销毁
    void EnableInactiveRelease(int timeout)
    {
        _timeout = timeout;
        _enable_inactive_release = true;
    }
    // ⽤于添加⼀个定时任务
    void RunAfter(const Functor &task, int delay)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this,
                                      task, delay));
    }
    void Start()
    {
        _pools.Init();
        LOG(DEBUG, "线程池初始化完毕!\n");
        _baseloop.Start();
    }
};
class NetWork
{
public:
    NetWork()
    {
        EnabelFILTRATION();
        LOG(DEBUG, "捕获SIGPIPE信号!\n");
        signal(SIGPIPE, SIG_IGN);
    }
};
static NetWork work;